package cn.jason.ymcc.service.impl;

import cn.jason.ymcc.constants.CommonConstants;
import cn.jason.ymcc.constants.SmsCodeConstants;
import cn.jason.ymcc.constants.YmccError;
import cn.jason.ymcc.domain.MessageSms;
import cn.jason.ymcc.dto.RedisRegisterDto;
import cn.jason.ymcc.exception.GlobalException;
import cn.jason.ymcc.service.IMessageSmsService;
import cn.jason.ymcc.service.IVerifyCodeService;
import cn.jason.ymcc.util.AssertUtil;
import cn.jason.ymcc.util.StrUtils;
import cn.jason.ymcc.util.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate<Object,Object>  redisTemplate;

    @Autowired
    private SmsCodeConstants smsCodeConstants;

    @Autowired
    private IMessageSmsService messageSmsService;
    @Override
    public String imageCode(String key) {
        if (!StringUtils.hasLength(key)) {
            throw new GlobalException("key不能为空！！！");
        }
//        。生成code
        String code = StrUtils.getComplexRandomString(4);
//        。保存redis，设置过期时间
        redisTemplate.opsForValue().set(
                key,
                code,
                5,//过期时间
                TimeUnit.MINUTES);
//        。使用2D引擎把code画成图
//        。把图使用Base64编码成字符串
//        。返回Base64编码的字符串
        return VerifyCodeUtils.verifyCode(100, 38, code);
    }


    /**
     * 发送注册验证码逻辑
     * @param mobile
     */
    @Override
    public void smsCode(String mobile) {
        //校验
        AssertUtil.isNotEmpty(mobile,YmccError.COMMON_PHONE_NO_EMPTY.getMessage());
        //@TODO     黑名单
        AssertUtil.isPhone(mobile,YmccError.COMMON_PHONE_NO_EMPTY.getMessage());//手机号不合法
        //验证码
        String key = String.format(CommonConstants.REGISTER_PHONE_PRIFIX, mobile);//register:158234234
        Date now = new Date();
        //校验手机号是否发送过验证码
        Object o = redisTemplate.opsForValue().get(key);
        String code = null;
        if(o != null){
            RedisRegisterDto registerDto = (RedisRegisterDto) o;
            boolean canSend = (now.getTime() - registerDto.getTime()) / 1000 > smsCodeConstants.getInterval();
            AssertUtil.isTrue(canSend,YmccError.COMMON_VIOLATION.getMessage());
            code = registerDto.getCode();
        }else{
            //生成验证码
            code = StrUtils.getRandomString(smsCodeConstants.getSize());
        }
        //存储验证码
        RedisRegisterDto redisRegisterDto = new RedisRegisterDto(code, now.getTime());
        redisTemplate.opsForValue().set(key,redisRegisterDto,smsCodeConstants.getTimeout(), TimeUnit.SECONDS);
        //发送验证码短信
        String message = String.format(smsCodeConstants.getSmsmessage(), code);
        log.info(message);
        //存储发送信息到数据库
        saveMessageSms(now, code, message);
    }


    private void saveMessageSms(Date now, String code,String message) {
        MessageSms messageSms = new MessageSms();
        messageSms.setContent(message);
        messageSms.setSendTime(now);
        messageSms.setTitle(smsCodeConstants.getTitle());
        // 获取请求体 request
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        messageSms.setIp(request.getRemoteAddr());
        messageSmsService.insert(messageSms);
    }
}